/***********************************************************************************************************************
**	filename: dbg.h
**	author: Echo Zhang @2021-05-08
**  e-mail: not_xx@126.com
***********************************************************************************************************************/

#ifndef DBG_INCLUDED
#define DBG_INCLUDED

#include "../user_types.h"

#if defined(USING_PRINTF)
#if defined(USING_STD_PRINTF)
#include <stdio.h>
#define std_printf(format, ...)					printf(format, ##__VA_ARGS__)
#else
void std_printf(const char *fmt, ...);
#endif
#else
#define std_printf(format, ...)
#endif

#define app_exit(val)							do{dbg_msg("exit: %u", val);while(true);} while(0)


#if defined(DBG_MODE)
#define dbg_printf(format, ...)					std_printf("%s#%u " format "\n", __FILE__, __LINE__, ##__VA_ARGS__)
#define sys_printf(format, ...)					dbg_printf(format, ##__VA_ARGS__)
#else
#define dbg_printf(format, ...)
#define sys_printf(format, ...)					std_printf(format "\n", ##__VA_ARGS__)
#endif

#define dbg_wng(format, ...)					dbg_printf("WARNING " format, ##__VA_ARGS__)
#define dbg_err(format, ...)					dbg_printf("ERROR " format, ##__VA_ARGS__)

#define sys_msg(format, ...)					sys_printf(format, ##__VA_ARGS__)
#define sys_wng(format, ...)					sys_printf("WARNING " format, ##__VA_ARGS__)
#define sys_err(format, ...)					sys_printf("ERROR " format, ##__VA_ARGS__)

#if defined(USING_ASSERT)
#define ASSERT(cond)							do{if(!(cond)){dbg_printf("ASSERT FAILED TO EXIT"); app_exit(163);}}while(0)
#else
#define ASSERT(cond)
#endif

#define dbg_msg(format, ...)					dbg_printf(format, ##__VA_ARGS__)
#define dbg_trace_msg()							dbg_printf("TRACE MESSAGE!")

#define dbg_print_int(value)                    dbg_printf(#value": %d", (value))
#define dbg_print_uint(value)                   dbg_printf(#value": %u", (value))
#define dbg_print_xint(value)                   dbg_printf(#value": 0x%X", (value))
#define dbg_print_float(value)                  dbg_printf(#value": %f", (value))
#define dbg_print_double(value)					dbg_printf(#value": %lf", (value))
#define dbg_print_string(value)                 dbg_printf(#value": %s", (value))

#if defined(USING_CHECK_MSG)
#define _dbg_check_msg(format, ...)				dbg_msg(format, ##__VA_ARGS__)
#else
#define _dbg_check_msg(format, ...)
#endif

#define exit_if_failed(cond, val)				do{if(!(cond)){dbg_printf("ASSERT FAILED TO EXIT %d", (si32)(val)); app_exit(val);}}while(0)
#define return_if_failed(cond)					do{if(!(cond)){_dbg_check_msg("ASSERT FAILED TO RETURN"); return;}}while(0)
#define return_val_if_failed(cond, val)			do{if(!(cond)){_dbg_check_msg("ASSERT FAILED TO RETURN %d", (si32)(val)); return(val);}}while(0)

#if defined(DBG_MODE) && defined(USING_PRINTF)
void _dbg_print_bytes_as_hex(const char *filename, int lineNum, const char *title, const void *bytes, Size_DT bytesLen);
void _dbg_print_bytes_as_string(const char *filename, int lineNum, const char *title, const void *bytes, Size_DT bytesLen);
#define dbg_print_bytes_as_hex(title, bytes, bytesLen)		_dbg_print_bytes_as_hex(__FILE__, __LINE__, (title), (bytes), (bytesLen))
#define dbg_print_bytes_as_string(title, bytes, bytesLen)	_dbg_print_bytes_as_string(__FILE__, __LINE__, (title), (bytes), (bytesLen))
#else
#define dbg_print_bytes_as_hex(title, bytes, bytesLen)
#define dbg_print_bytes_as_string(title, bytes, bytesLen)
#endif

#endif	/* DBG_INCLUDED */

/***********************************************************************************************************************
**	endline
***********************************************************************************************************************/
